/*******************************************************************************************
 *      @name   pipe_test.c
 *      @brief  这是在linux系统下使用匿名管道实现内部进程间的通信，目的是学习匿名管道的应用
 *      @date   2025/02/08
 *      @author cecelmx@126.com 
 *      @note
 *          1.匿名管道只可以在内部进程间使用(具有亲缘关系，通过fork函数创建的进程)
 *          2.匿名管道需要使用pipe函数进行创建，可以得到访问匿名管道的2个文件描述符 int pipefd[2]
 * 
 *      @version  xx.xx.xx   主版本号.次版本号.修正版本号
 * 
 *      CopyRight (c)   2024-2025   Your Name     All Right Reserved
 * 
 * ****************************************************************************************/
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/wait.h>
#include <stdlib.h>
int main()
{
    int child_pid;
    
    int pipefd[2] ={0}; //用于存储匿名管道的文件描述符 pipefd[0] -- R   pipefd[1] -- W

    //1.创建匿名管道
    int ret = pipe(pipefd);
    if(ret == -1)
    {
        fprintf(stderr,"pipe error,%s\n",strerror(errno));
        exit(-1);
    }

    //2.调用fork创建子进程，子进程会继承父进程的数据段
    child_pid = fork();

    //3.区分父进程和子进程，因为父进程和子进程具有各自独立的进程空间
    if(child_pid > 0)
    {
        //父进程,从管道读取数据
        wait(NULL); //具有阻塞性质的，如果子进程没结束，则wait函数会阻塞

        char buf[128] ={0};
        read(pipefd[0],buf,sizeof(buf));
        printf("I am parent,my process pid = %d,read form pipe is [%s]\n",getpid(),buf);
        
    }
    else if(child_pid == 0)
    {
        //子进程,向管道写入数据
        char buf[128] ={0};
        sprintf(buf,"I am child,my process pid = %d,my parent pid = %d",getpid(),getppid());
        write(pipefd[1],buf,sizeof(buf));
    }
    else
    {
        //异常时
        fprintf(stderr,"fork error,errno = %d,%s\n",errno,strerror(errno));
        return -1;
    }

    return 0;
}